//
//  contain_class.cpp
//  learnC++
//
//  Created by liuzhibing on 2018/6/11.
//  Copyright © 2018年 yunfan.com. All rights reserved.
//

#include "contain_class.hpp"

IntArray::IntArray():m_data(nullptr),m_length(0){
    
}

IntArray::IntArray(int length):m_length(length){
    assert(length > 0);
    if (length > 0) {
        m_data = new int[length]();
    }else{
        m_data = nullptr;
    }
}

IntArray::IntArray(const std::initializer_list<int> &list):IntArray(static_cast<int>(list.size())){
    int count = 0;
    for(auto &element : list){
        m_data[count] = element;
        ++count;
    }
}

IntArray::~IntArray(){
    delete [] m_data;
}

void IntArray::erase(){
    if (!m_data) {
        return;
    }
    
    delete [] m_data;
    m_data = nullptr;
    m_length = 0;
}

int &IntArray::operator[](int index){
    assert(index >= 0 && index < m_length);
    return m_data[index];
}

void IntArray::reallocate(int newLength){
    if (newLength <= 0) {
        return;
    }
    erase();
    
    m_data = new int[newLength]();
    m_length = newLength;
}

void IntArray::resize(int newLength){
    if (newLength == m_length) {
        return;
    }
    
    if (newLength <= 0) {
        return;
    }
    
    int *data = new int[newLength]();
    
    int elementToCopy = (m_length > newLength) ? newLength : m_length;
    
    for (int i = 0; i < elementToCopy; ++i) {
        data[i] = m_data[i];
    }
    
    delete [] m_data;
    
    m_data = data;
    
    m_length = newLength;
    
}

//0 1 2 3   in  2
void IntArray::insertBefore(int value,int index){
    assert(index >= 0 && index <= m_length);
    int *data = new int[m_length+1]();
    
    //copy
    for (int i = 0; i < index; ++i) {
        data[i] = m_data[i];
    }
    
    data[index] = value;
    
    for (int i = index; i < m_length; ++i) {
        data[i+1] = m_data[i];
    }
    
//    for (int i = 0; i < m_length+1; ++i) {
//        std::cout << data[i] << "\n";
//    }
    
    
    delete [] m_data;
    m_data = data;
    m_length += 1;
}

void IntArray::remove(int index){
    
    assert(index >= 0 && index < m_length);
    
    if (m_length == 1)
    {
        erase();
        return;
    }
    
    int *data = new int[m_length-1];
    
    // Copy
    for (int before=0; before  < index; ++before)
        data[before] = m_data[before];
    
    for (int after=index+1; after < m_length; ++after )
        data[after-1] = m_data[after];
    
    delete[] m_data;
    m_data = data;
    --m_length;
}

void IntArray::insertAtBeginning(int value){
    insertBefore(value, 0);
}

void IntArray::insertAtEnd(int value){
    insertBefore(value, m_length);
}

int IntArray::getLength(){
    return m_length;
}

IntArray &IntArray::operator=(const std::initializer_list<int> &list){
    
    // If the new list is a different size, reallocate it
    if (list.size() != static_cast<size_t>(m_length))
    {
        // delete any existing elements
        delete[] m_data;
        
        // reallocate array
        m_length = static_cast<int>(list.size());
        m_data = new int[m_length];
    }
    
    // Now initialize our array from the list
    int count = 0;
    for (auto &element : list)
    {
        m_data[count] = element;
        ++count;
    }
    return *this;
}

